import { useUserStore } from '@/stores'
import type { User } from '@/types/user'
import axios from 'axios'
import { showFailToast } from 'vant'
import 'vant/es/toast/style'
import { useRouter } from 'vue-router'
// router是路由对象，包含路由对象相关的方法，如push()、back()、replace()
// route对象，包含路由对象的信息，query、params
// const route = useRoute()
const router = useRouter()
// 1.接口的基准地址
// export const baseUrl = 'https://consult-api.itheima.net/'
export const baseUrl = import.meta.env.VITE_API_URL
// 2.创建实例
const instance = axios.create({
  // 基准地址
  baseURL: baseUrl,
  // 响应的超时时间
  timeout: 5000
})

// 3.1 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送需要携带token请求之前在请求头中添加token
    // 获取token
    const store = useUserStore()
    if (store.user?.token) {
      config.headers.Authorization = `Bearer ${store.user.token}`
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 3.2 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // HTTP响应状态码为200，但是业务状态码非10000的都是错误，需要提前处理
    if (response.data.code !== 10000) {
      showFailToast(response.data.message)
      // 可以将异常信息通过Promise.reject抛出，将来在使用时可以是catch进行捕获，根据不同的业务状态码进行不同的业务处理
      return Promise.reject(response.data)
    }
    // 剥离掉最外层data
    return response.data
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 401错误：token异常(没携带、错误、过期)
    if (error.response.status === 401) {
      // 移动端：首次登录成功后会返回token和refresh_token,token的有效期一般是2小时,refresh_token的有效期一般很长，移动端为了用户体验度，不建议token失效，立即退出登录然后重新登录。正确做法：无感登录;无感登录的实现步骤：1.先判断token是否过期，如果token过期了，再判断refresh_token是否过期，如果2个都过期，让用户重新登录；2.如果refresh_token没有过期，会拿着refresh_token调换取最新token的api接口拿到最新的token并保存起来，并同时发起当前次未完成的请求
      // pc端：token失效，删除用户相关数据，跳转到登录页面重新发起登录，生成最新的token
      // 比如当前访问的页面是/user模块，token过期，跳到登录页面，登录成功，应该要回跳到上次token失效时访问的地址
      // path: /user  fullpath: /user?a=100
      // 删除用户信息
      showFailToast('token失效,请重新登录')
      const store = useUserStore()
      store.delUser()
      router.push(`/login?returnUrl=${router.currentRoute.value.fullPath}`)
    }
    return Promise.reject(error)
  }
)

// 对axios返回的数据做类型限制
type Data<T> = {
  code: number
  message: string
  data: T
}

// 4. 请求工具函数
/* const request = <T>(url: string, method = 'get', submitData?: object) => {
  return instance.request<T, Data<T>>({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
} */

function request<T>(url: string, method = 'get', submitData?: object) {
  return instance.request<T, Data<T>>({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}

export default request
